/*
 * @Author: wangchao
 * @Date: 2024-08-22 10:58:33
 * @LastEditors: wangchao
 * @LastEditTime: 2024-10-10 13:20:05
 * @FilePath: \JD-RTT-Driver\small_modbus_rtu\rtu_mb_master_app.c
 * @Description:
 * Copyright (c) 2024 by Bingshan Guardian, All Rights Reserved.
 */

#include "stdio.h"
#include "string.h"
#include "board.h"
#include "rtu_mb.h"
#include "rtu_virtualIO.h"
#define DBG_TAG "VB_RTU"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

/* 定义互斥量控制块 */
static rt_mutex_t mb_master_wr_mux = RT_NULL;

// 收发控制引脚回调函数
static int uart_rts(int on)
{
    return 0;
}

static void rs485_pin_init(void)
{
    ;
}

/***
 * 读取从站信息定义
 */

uint8_t rtu_master_print_enable = 0;

static rtu_mb_t modbus_rtu_master = {0};

rt_bool_t set_rtu_master_print_enable(uint8_t val)
{
    rtu_master_print_enable = val;
}

uint8_t get_rtu_master_print_enable(void)
{
    return rtu_master_print_enable;
}

static uint16_t recv_buff[32];

/**
 *  电压板通信故障统计
 */
#define COMM_ERROR_MAX_COUNT 20
static rt_uint16_t vb1_comm_error_count = 0;
static rt_uint16_t vb2_comm_error_count = 0;
static rt_uint16_t vb3_comm_error_count = 0;

rt_uint16_t get_vb_comm_error_count(rt_uint8_t chx)
{
    rt_uint16_t ret = 0;
    switch (chx)
    {
        case 1:
            ret = vb1_comm_error_count;
            break;
        case 2:
            ret = vb2_comm_error_count;
            break;
        case 3:
            ret = vb3_comm_error_count;
            break;
    }
    return ret;
}

static rt_uint16_t volt_board_1_value[11] = {0};
static rt_uint16_t volt_board_2_value[11] = {0};

static rt_uint16_t A_side_volt[7] = {0};
static rt_uint16_t B_side_volt[7] = {0};
static rt_uint16_t A_OCV = 0;
static rt_uint16_t B_OCV = 0;
static rt_bool_t AB_side_volt_ready = RT_FALSE;

rt_uint16_t get_a_side_volt(rt_uint8_t chx)
{
    if (AB_side_volt_ready)
    {
        rt_uint8_t index = chx - 1;
        return A_side_volt[index];
    }
    return 0;
}

rt_uint16_t get_b_side_volt(rt_uint8_t chx)
{
    if (AB_side_volt_ready)
    {
        rt_uint8_t index = chx - 1;
        return B_side_volt[index];
    }
    return 0;
}

rt_uint16_t get_eocv(rt_uint8_t chx)
{
    if (!AB_side_volt_ready)
    {
        return 0;
    }
    return (chx == 1) ? A_OCV : (chx == 2) ? B_OCV : 0;
}

rt_bool_t is_volt_data_ready(void)
{
    return AB_side_volt_ready;
}

rt_bool_t volt_borad_comm_fault = RT_FALSE;

void master_poll(rtu_mb_t* smb_master)
{
    int rc = 0;
    rt_uint8_t index = 0;
    //
    rt_thread_mdelay(300);

    rt_mutex_take(mb_master_wr_mux, RT_WAITING_FOREVER);
    /**
     *  读取 - 1 #电压板 (起始地址36, 长度11)
     */
    rmb_error_recovery(smb_master);
    rmb_set_slave(smb_master, 0x1);
    rc = rmb_read_registers(smb_master, 36, 11, recv_buff);
    if (rc >= MODBUS_OK)
    {
        if (rtu_master_print_enable)
            rt_kprintf("VB-1#:");
        for (index = 0; index < 11; index++)
        {
            if (rtu_master_print_enable)
                rt_kprintf("[%d]", rtu_aio_get_val(recv_buff, index));
            volt_board_1_value[index] = rtu_aio_get_val(recv_buff, index);
        }
        if (rtu_master_print_enable)
            rt_kprintf("\r\n");

        vb1_comm_error_count = 0;
    }
    else
    {
        // LOG_E("vb rtu read vb 1# error:%d", rc);
        vb1_comm_error_count++;
        if (vb1_comm_error_count > COMM_ERROR_MAX_COUNT)
        {
            vb1_comm_error_count = COMM_ERROR_MAX_COUNT;
        }
    }
    rt_mutex_release(mb_master_wr_mux);
    //
    rt_thread_mdelay(300);

    rt_mutex_take(mb_master_wr_mux, RT_WAITING_FOREVER);
    /**
     *  读取 - 2 #电压板 (起始地址36, 长度11)
     */
    rmb_error_recovery(smb_master);
    rmb_set_slave(smb_master, 0x2);
    rc = rmb_read_registers(smb_master, 36, 11, recv_buff);
    if (rc >= MODBUS_OK)
    {
        if (rtu_master_print_enable)
            rt_kprintf("VB-2#:");
        for (index = 0; index < 11; index++)
        {
            if (rtu_master_print_enable)
                rt_kprintf("[%d]", rtu_aio_get_val(recv_buff, index));
            volt_board_2_value[index] = rtu_aio_get_val(recv_buff, index);
        }
        if (rtu_master_print_enable)
            rt_kprintf("\r\n");

        vb2_comm_error_count = 0;
    }
    else
    {
        // LOG_E("vb rtu read vb 2# error:%d", rc);
        vb2_comm_error_count++;
        if (vb2_comm_error_count > COMM_ERROR_MAX_COUNT)
        {
            vb2_comm_error_count = COMM_ERROR_MAX_COUNT;
        }
    }
    rt_mutex_release(mb_master_wr_mux);
    //
    /**
     *  解析电压板通讯数据
     */
    //
    A_OCV = volt_board_1_value[10];
    B_OCV = volt_board_2_value[10];
    //
    for (index = 0; index < 7; index++)
    {
        A_side_volt[index] = volt_board_1_value[index];
    }
    for (index = 0; index < 7; index++)
    {
        B_side_volt[index] = volt_board_2_value[index];
    }
    //
    if (vb1_comm_error_count == 0 && vb2_comm_error_count == 0 && vb3_comm_error_count == 0)
    {
        AB_side_volt_ready = RT_TRUE;
        volt_borad_comm_fault = RT_FALSE;
    }
    else if (vb1_comm_error_count == COMM_ERROR_MAX_COUNT && vb2_comm_error_count == COMM_ERROR_MAX_COUNT && vb3_comm_error_count == COMM_ERROR_MAX_COUNT)
    {
        AB_side_volt_ready = RT_FALSE;
    }
    //
    if (vb1_comm_error_count == COMM_ERROR_MAX_COUNT || vb2_comm_error_count == COMM_ERROR_MAX_COUNT || vb3_comm_error_count == COMM_ERROR_MAX_COUNT)
    {
        volt_borad_comm_fault = RT_TRUE;
    }
}

void rtu_master_write_to_slave(int addr, int val)
{
    return;
    // int rc = 0, retry = 0;

    // rt_mutex_take(mb_master_wr_mux, RT_WAITING_FOREVER);

    // rtu_mb_t* smb_master = &modbus_rtu_master;

    // for (retry = 0; retry < 15; retry++)
    // {
    //     rc = rmb_write_register(smb_master, addr, val);
    //     if (rc >= MODBUS_OK)
    //     {
    //         rt_kprintf("mb rtu write to slave ok: addr:%d val:%d retry:%d\n", addr, val, retry);
    //         break;
    //     }
    //     else
    //     {
    //         rt_kprintf("mb rtu write to slave error: %d retry:%d\n", rc, retry);
    //     }
    //     rt_thread_mdelay(retry * 100);
    // }

    // rt_mutex_release(mb_master_wr_mux);
}

static void volt_mbrtu_master_thread_entry(void* param)
{
    rtu_mb_t* smb_master = param;

    rs485_pin_init();

    rmb_init(smb_master, MODBUS_CORE_RTU, rmb_port_rtdevice_create(RTU_UART_DEVICE_NAME));

    struct serial_configure serial_config;
    serial_config.baud_rate = BAUD_RATE_9600;
    serial_config.data_bits = DATA_BITS_8;
    serial_config.stop_bits = STOP_BITS_1;
    serial_config.bufsz = 512;
    serial_config.parity = PARITY_NONE;
    rmb_rtu_set_serial_config(smb_master, &serial_config);

    rmb_rtu_set_serial_rts(smb_master, uart_rts);
    rmb_rtu_set_oflag(smb_master, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);

    rmb_connect(smb_master);
    while (1)
    {
        master_poll(smb_master);
    }
}

int bms_volt_mbrtu_master_thread(void)
{
    rt_thread_t tid;

    mb_master_wr_mux = rt_mutex_create("mb_wr_mux", RT_IPC_FLAG_PRIO);

    if (mb_master_wr_mux != RT_NULL)
        rt_kprintf("mb wr mutx create success\n\n");

    tid = rt_thread_create("master", volt_mbrtu_master_thread_entry, &modbus_rtu_master, B_MB_RTU_COM_STACK_SIZE, B_MB_RTU_MASTER_COM_THREAD_PRIORITY, 15);
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }
    else
    {
        goto __exit;
    }
    return RT_EOK;
__exit:
    if (tid)
        rt_thread_delete(tid);
    return RT_ERROR;
}
